package com.sheng.leetcode.year2022.month07.day29;

import org.junit.Test;

/**
 * @author liusheng
 * @date 2022/07/29
 *
 * 593. 有效的正方形
 *
 * 给定2D空间中四个点的坐标 p1, p2, p3 和 p4，如果这四个点构成一个正方形，则返回 true 。
 * 点的坐标 pi 表示为 [xi, yi] 。输入 不是 按任何顺序给出的。
 * 一个 有效的正方形 有四条等边和四个等角(90度角)。
 *
 * 示例 1:
 * 输入: p1 = [0,0], p2 = [1,1], p3 = [1,0], p4 = [0,1]
 * 输出: True
 *
 * 示例 2:
 * 输入：p1 = [0,0], p2 = [1,1], p3 = [1,0], p4 = [0,12]
 * 输出：false
 *
 * 示例 3:
 * 输入：p1 = [1,0], p2 = [-1,0], p3 = [0,1], p4 = [0,-1]
 * 输出：true
 *
 * 提示:
 *
 * p1.length == p2.length == p3.length == p4.length == 2
 * -104 <= xi, yi <= 104
 *
 * 来源：力扣（LeetCode）
 * 链接：https://leetcode.cn/problems/valid-square
 * 著作权归领扣网络所有。商业转载请联系官方授权，非商业转载请注明出处。
 */
public class LeetCode0593 {

    @Test
    public void test01() {
//        int[] p1 = {0,0}, p2 = {1,1}, p3 = {1,0}, p4 = {0,1};
//        int[] p1 = {0,0}, p2 = {1,1}, p3 = {1,0}, p4 = {0,12};
//        int[] p1 = {1,0}, p2 = {-1,0}, p3 = {0,1}, p4 = {0,-1};
        //判断对边和临边
//        int[] p1 = {1,0}, p2 = {0,1}, p3 = {-1,0}, p4 = {0,-1};
        //长方形
//        int[] p1 = {0,0}, p2 = {5,0}, p3 = {5,4}, p4 = {0,4};
        //等边菱形
//        int[] p1 = {1,1}, p2 = {5,3}, p3 = {3,5}, p4 = {7,7};
        //点重复
        int[] p1 = {1,1}, p2 = {1,1}, p3 = {1,1}, p4 = {1,1};
        System.out.println(new Solution().validSquare(p1, p2, p3, p4));
    }

}
class Solution {
    public boolean validSquare(int[] p1, int[] p2, int[] p3, int[] p4) {
        //点重复
        if (p1[0] == p2[0] && p1[1] == p2[1]) {
            return false;
        }
        //问题，如何判断哪两个点是对点，点与点之间的长度
        //边 p1->p2(x1, y1) 和边 p1->p3(x2, y2) 和边 p1->p4(x3, y3) 的大小
        int x1 = p1[0] - p2[0];
        int y1 = p1[1] - p2[1];
        int x2 = p1[0] - p3[0];
        int y2 = p1[1] - p3[1];
        int x3 = p1[0] - p4[0];
        int y3 = p1[1] - p4[1];
        int length1 = x1 * x1 + y1 * y1;
        int length2 = x2 * x2 + y2 * y2;
        int length3 = x3 * x3 + y3 * y3;
        if (length1 > length2) {
            //p1到p2是斜角边
            return judge(p1, p2, p3, p4);
        } else if (length2 > length1) {
            //p1到p3是斜角边
            return judge(p1, p3, p2, p4);
        } else {
            //p1到p4是斜角边
            return judge(p1, p4, p3, p2);
        }
    }

    public boolean judge(int[] p1, int[] p2, int[] p3, int[] p4) {
        //判断相对的向量方向相同的同时，每条边的长度相同，即为true
        //边 p1->p3(x1, y1) 和边 p4->p2(x2, y2) 的方向及大小
        int x1 = p1[0] - p3[0];
        int y1 = p1[1] - p3[1];
        int x2 = p4[0] - p2[0];
        int y2 = p4[1] - p2[1];

        //边 p1->p4(x3, y3) 和边 p3->p2(x4, y4) 的方向及大小
        int x3 = p1[0] - p4[0];
        int y3 = p1[1] - p4[1];
        int x4 = p3[0] - p2[0];
        int y4 = p3[1] - p2[1];
        if (x1 * y2 == x2 * y1
                && x1 * x1 + y1 * y1 == x2 * x2 + y2 * y2
                && x3 * y4 == x4 * y3
                && x3 * x3 + y3 * y3 == x4 * x4 + y4 * y4
                //判断临边边长相等
                && x3 * x3 + y3 * y3 == x1 * x1 + y1 * y1
                //判断临边互相垂直
                && x1 * x3 + y1 * y3 == 0) {
            return true;
        }
        return false;
    }
}

//根据题意进行模拟即可。
//
//从给定的 44 个顶点中选 33 个顶点，检查其能否形成「直角三角形」，同时保存下来首个直角三角形的直角边边长，
//供后续其余直角三角形进行对比（注意不能共点，即直角边长不能为 00）。
//
//class Solution {
//    long len = -1;
//    public boolean validSquare(int[] a, int[] b, int[] c, int[] d) {
//        return calc(a, b, c) && calc(a, b, d) && calc(a, c, d) && calc(b, c, d);
//    }
//    boolean calc(int[] a, int[] b, int[] c) {
//        long l1 = (a[0] - b[0]) * (a[0] - b[0]) + (a[1] - b[1]) * (a[1] - b[1]);
//        long l2 = (a[0] - c[0]) * (a[0] - c[0]) + (a[1] - c[1]) * (a[1] - c[1]);
//        long l3 = (b[0] - c[0]) * (b[0] - c[0]) + (b[1] - c[1]) * (b[1] - c[1]);
//        boolean ok = (l1 == l2 && l1 + l2 == l3) || (l1 == l3 && l1 + l3 == l2) || (l2 == l3 && l2 + l3 == l1);
//        if (!ok) return false;
//        if (len == -1) len = Math.min(l1, l2);
//        else if (len == 0 || len != Math.min(l1, l2)) return false;
//        return true;
//    }
//}
//
//作者：AC_OIer
//链接：https://leetcode.cn/problems/valid-square/solution/by-ac_oier-lwdf/
//来源：力扣（LeetCode）
//著作权归作者所有。商业转载请联系作者获得授权，非商业转载请注明出处。
